#include "StdAfx.h"
#include "dll_object.h"
#include "im_svc_impl.h"
#include "im_packet_impl.h"
#include "chat_mgr.h"
#include "tribe_chat_mgr.h"
#include "ent_chat_mgr.h"
#include "user_define_msg_parser_impl.h"

dll_object* g_dll_obj = NULL;

sm_driver* 
get_sm_driver()
{
	return g_dll_obj->im_svc_impl_->sm_drv_;
}


dll_object::dll_object(void)
{
	imain_ = NULL;
	im_svc_impl_ = new im_svc_impl;
	chat_mgr_ = new chat_mgr;
	tribe_chat_mgr_ = new tribe_chat_mgr();
	ent_chat_mgr_ = new ent_chat_mgr();
	chatroom_chat_mgr_ = new chatroom_chat_mgr();
	my_ims_id_ = 0;
	my_local_addr_.ip = 0; my_local_addr_.port = 0;
	my_pub_addr_.ip = 0; my_pub_addr_.port = 0;
	last_online_status_ = aot::e_status_online;
	force_out_ = false;
	is_first_regist_ = true;
}

dll_object::~dll_object(void)
{
	th_pool_.stop();

	if( im_svc_impl_ )
	{
		delete im_svc_impl_;
		im_svc_impl_ = NULL;
	}
	if( chat_mgr_ )
	{
		delete chat_mgr_;
		chat_mgr_ = NULL;
	}
	if( tribe_chat_mgr_ )
	{
		delete tribe_chat_mgr_;
		tribe_chat_mgr_ = NULL;
	}
	if( ent_chat_mgr_ )
	{
		delete ent_chat_mgr_;
		ent_chat_mgr_ = NULL;
	}
	if( chatroom_chat_mgr_ )
	{
		delete chatroom_chat_mgr_;
		chatroom_chat_mgr_ = NULL;
	}
}

bool dll_object::query_interface(void** out, const char* key)
{
	if( NULL == key )
		return false;

	if( 0 == strcmp(key, "iim_svc") )
	{
		*out = (aot::im::iim_svc*)this->im_svc_impl_;
		return true;
	}
	if( 0 == strcmp(key, "iim_packet") )
	{
		aot::im::iim_packet* p = im_packet_impl::create_pkt();
		*out = p;
		return true;
	}
	if ( 0 == strcmp(key, "iuser_define_msg_parser") )
	{
		aot::im::iuser_define_msg_parser* p = new user_define_msg_parser_impl;
		*out = p;
		return true;
	}

	return false;
}

bool dll_object::query_interface_by_iid (void** out, int key)
{
	switch( key )
	{
	case aot::im::iim_svc::iid:
		{
			*out = (aot::im::iim_svc*)this->im_svc_impl_;
			return true;
		}
		break;
	case aot::im::iim_packet::iid:
		{
			aot::im::iim_packet* p = im_packet_impl::create_pkt();
			*out = p;
			return true;
		}
		break;
	case aot::im::iuser_define_msg_parser::iid:
		{
			aot::im::iuser_define_msg_parser* p = new user_define_msg_parser_impl;
			*out = p;
			return true;
		}
	default:
		return false;
	}
	return false;
}

static bool 
__file_exist(const char *fn)
{
	bool ret = false;
	WIN32_FIND_DATA fd; 
	HANDLE find = FindFirstFile(fn, &fd);
	if ( (find !=  INVALID_HANDLE_VALUE) ) 
	{
		if( !(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
		{
			ret = true;
		}
	}
	FindClose(find);

	return ret;
}

bool dll_object::on_regist(aot::tt::idll::dll_regist_param_t* p, aot::tt::result_t* ret /*= NULL*/)
{
	init_log(p->mi);
	this->imain_ = p->mi;

	if( !p->mi->query_interface(this->aot_inet_dll_, "idll.aot_inet.dll") )
	{
		aot_log_error(AOT_LM_ERROR, "find idll.aot_inet.dll failed");
		return false;
	}

	if( !p->mi->query_interface_ex(this->tata_op_, "idll.global_data.dll", "itata_op"))
	{
		aot_log_error(AOT_LM_ERROR, "query_interface [itata_op] from [idll.global_data.dll] failed");
		return false;
	}

	if( !this->tata_op_->create_user_mgr(this->curr_user_) )
	{
		aot_log_error(AOT_LM_ERROR, "create_user_mgr from [idll.global_data.dll] failed");
		return false;
	}

	if( !this->tata_op_->create_user_status_mgr(this->user_status_mgr_) )
	{
		aot_log_error(AOT_LM_ERROR, "create_user_status_mgr from [idll.global_data.dll] failed");
		return false;
	}

	if( !this->tata_op_->create_enterprise(this->enterprise_op_) )
	{
		aot_log_error(AOT_LM_ERROR, "create_enterprise from [idll.global_data.dll] failed");
		return false;
	}

	if( !this->tata_op_->create_tribe_mgr(this->tribe_mgr_) )
	{
		aot_log_error(AOT_LM_ERROR, "create_tribe_mgr from [idll.global_data.dll] failed");
		return false;
	}
	
	if( !this->tata_op_->create_buddy_mgr(this->buddy_mgr_) )
	{
		aot_log_error(AOT_LM_ERROR, "create_buddy_mgr from [idll.global_data.dll] failed");
		return false;
	}

	if( !this->tata_op_->create_user_lst_mgr(this->user_lst_mgr_) )
	{
		aot_log_error(AOT_LM_ERROR, "create_user_lst_mgr from [idll.global_data.dll] failed");
		return false;
	}
	

	if( !this->im_svc_impl_->init() )
	{
		aot_log_error(AOT_LM_ERROR, "im_svc_impl_->init() failed");
		return false;
	}

	th_pool_.start();

	return true;
}

void 
dll_object::init_log(aot::tt::imain* imain_obj)
{
	aot::tt::ilog *log_obj = NULL;

	if(!imain_obj->query_interface((void**)&log_obj, "ilog"))
	{
		return;
	}

	aot_log_init(log_obj);
	aot_log_cfg_from_file("idll.aot_im.dll", NULL);
	aot_log_debug(AOT_LM_DEBUG, "%s", "\n\n aot_im log initial ok !");
}

int	
dll_object::on_command (aot::tt::command_t* cmd, aot::tt::result_t* ret/* = NULL*/)
{
	return -1;
}

bool
dll_object::query_interface_from_aot_inet_dll(void** out, int key)
{
	*out = NULL;
	if( !this->aot_inet_dll_->query_interface_by_iid(out, key) || ( NULL == *out ) )
	{
		aot_log_error(AOT_LM_ERROR, "query_interface [iid = %d] from idll.aot_inet.dll failed", key);
		return false;
	}
	return true;
}